//
// Created by HP on 2025/11/14.
//

#include "User.h"

const std::string Role::User = "Adult";
const std::string Role::Student = "student";
const std::string Role::VIP = "vip";
const std::string Role::SuperAdmin = "superadmin";
const std::string Role::MaintenanceAdmin = "maintenanceadmin";
const std::string Role::ContentAdmin = "contentadmin";
const std::string Role::MoneyAdmin = "moneyadmin";
const std::string Role::frozen = "frozen";

User::User() : Model("users"){
    this->role = Role::User;
    setTableDefault("name", "VARCHAR(50) NOT NULL UNIQUE");
    setTableDefault("email", "VARCHAR(50) NOT NULL UNIQUE");
    setTableDefault("password", "VARCHAR(500) NOT NULL");
    setTableDefault("age", "INT NOT NULL");
    setTableDefault("idCardNumber", "VARCHAR(50) NOT NULL UNIQUE");
    setTableDefault("createdAt", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
    setTableDefault("role", "VARCHAR(50) NOT NULL DEFAULT '" + Role::User + "'");
}

void User::update(const std::string& key, const std::string& value) {
    if(key.empty()||value.empty()) {
        std::cerr << "Error: Key or value is empty" << std::endl;
        return;
    }

    if (!TableCols.count(key)) {
        std::cerr << "Error: Invalid key for user update" << std::endl;
        return;
    }

    if(Id.empty()) {
        std::cerr << "Error: User ID is empty" << std::endl;
        return;
    }

    const std::string updateSql = "UPDATE " + TableName + " SET " + key + " = '" + Model::escapeSqlLiteral(value) +
                                  "' WHERE id = '" + Model::escapeSqlLiteral(Id) + "';";

    // 执行 SQL 并输出详细错误信息
    int executeCode = DBConnector::getInstance()->execute(updateSql);
    if (executeCode == -1) {
        std::cerr << "init database failed: SQL execution error. SQL: " << updateSql << std::endl;
    } else {
        std::cout << "init database success. Table: " << TableName << std::endl;
    }
}

void User::bind(const std::string &key, const std::string &value) {
    if (!TableCols.count(key)) {
        std::cerr << "Error: Invalid key for user bind" << std::endl;
        return;
    }
    if (TableCols[key].find("UNIQUE")== std::string::npos&&key!="id") {
        std::cerr << "Error: Key is not unique for user bind" << std::endl;
        return;
    }

    const std::string selectSql =
            "SELECT * FROM " + TableName + " WHERE " + key + " = '" + Model::escapeSqlLiteral(value) + "'" + ";";
    std::vector<std::map<std::string, std::string>> result = DBConnector::getInstance()->query(selectSql);
    if (result.empty()) {
        std::cerr << "init database failed: SQL execution error or no result. SQL: " << selectSql << std::endl;
        return;
    }

    std::cout << "bind success. Table: " << TableName << std::endl;

    if(result.size() > 1) {
        std::cerr << "Error: Multiple users found with the same " << key << std::endl;
        return;
    } else if(result.size() == 1) {
        this->Id = result[0]["id"];
        this->Name = result[0]["name"];
        this->Email = result[0]["email"];
        this->Password = result[0]["password"];
        this->Age = result[0]["age"];
        this->IdCardNumber = result[0]["idCardNumber"];
        this->createdAt = result[0]["createdAt"];
        this->role = result[0]["role"];
        this->isBind = true;
    }
}

bool User::save() {
    std::string createUserSql = "INSERT INTO " + TableName + " (name, email, password, age, idCardNumber, role) VALUES ('" 
                                + Model::escapeSqlLiteral(Name) + "', '" 
                                + Model::escapeSqlLiteral(Email) + "', '" 
                                + Model::escapeSqlLiteral(Password) + "', " 
                                + Age + ", '" 
                                + Model::escapeSqlLiteral(IdCardNumber) + "', '" 
                                + Model::escapeSqlLiteral(role) + "');";
    int executeCode = DBConnector::getInstance()->execute(createUserSql);
    if (executeCode == -1) {
        std::cerr << "create user failed: SQL execution error. SQL: " << createUserSql << std::endl;
        return false;
    } else {
        std::cout << "create user success. Table: " << TableName << std::endl;
        return true;
    }
}
